import base64
import datetime
import hashlib
import hmac
import json
import ssl
import websocket
import _thread as thread
from datetime import datetime
from time import mktime
from urllib.parse import urlparse
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time


appid = "d3fb4c44"
api_secret = "OGNjNmY5N2M0NDhmZDQ4YzIxOTc2ZjUz"
api_key = "85311692ef36b5181251a367868fe9fe"
imageunderstanding_url = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image"


class Ws_Param(object):
    # 初始化
    def __init__(self, APPID, APIKey, APISecret, imageunderstanding_url):
        self.APPID = APPID
        self.APIKey = APIKey
        self.APISecret = APISecret
        self.host = urlparse(imageunderstanding_url).netloc
        self.path = urlparse(imageunderstanding_url).path
        self.ImageUnderstanding_url = imageunderstanding_url

    # 生成url
    def create_url(self):
        # 生成RFC1123格式的时间戳
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))

        # 拼接字符串
        signature_origin = "host: " + self.host + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + self.path + " HTTP/1.1"

        # 进行hmac-sha256进行加密
        signature_sha = hmac.new(
            self.APISecret.encode("utf-8"),
            signature_origin.encode("utf-8"),
            digestmod=hashlib.sha256,
        ).digest()

        signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding="utf-8")

        authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'

        authorization = base64.b64encode(authorization_origin.encode("utf-8")).decode(
            encoding="utf-8"
        )

        # 将请求的鉴权参数组合为字典
        v = {"authorization": authorization, "date": date, "host": self.host}
        # 拼接鉴权参数，生成url
        url = self.ImageUnderstanding_url + "?" + urlencode(v)
        # print(url)
        # 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释，比对相同参数时生成的url与自己代码生成的url是否一致
        return url


# 收到websocket错误的处理
def on_error(ws, error):
    print("### error:", error)


# 收到websocket关闭的处理
def on_close(ws, one, two):
    print(" ")


# 收到websocket连接建立的处理
def on_open(ws):
    thread.start_new_thread(run, (ws,))


def run(ws, *args):
    data = json.dumps(gen_params(appid=ws.appid, question=ws.question))
    ws.send(data)


# 收到websocket消息的处理
def on_message(ws, message):
    # print(message)
    data = json.loads(message)
    code = data["header"]["code"]
    if code != 0:
        print(f"请求错误: {code}, {data}")
        ws.close()
    else:
        choices = data["payload"]["choices"]
        status = choices["status"]
        content = choices["text"][0]["content"]
        #print(content, end="")
        global answer
        answer += content
        # print(1)
        if status == 2:
            ws.close()

        with open("analyze_res.txt",'w') as file:
            file.write(answer)


def gen_params(appid, question):

    data = {
        "header": {"app_id": appid},
        "parameter": {
            "chat": {
                "domain": "image",
                "temperature": 0.5,
                "top_k": 4,
                "max_tokens": 2028,
                "auditing": "default",
            }
        },
        "payload": {"message": {"text": question}},
    }

    return data


def main(appid, api_key, api_secret, imageunderstanding_url, question):

    wsParam = Ws_Param(appid, api_key, api_secret, imageunderstanding_url)
    websocket.enableTrace(False)
    wsUrl = wsParam.create_url()
    ws = websocket.WebSocketApp(
        wsUrl,
        on_message=on_message,
        on_error=on_error,
        on_close=on_close,
        on_open=on_open,
    )
    ws.appid = appid
    # ws.imagedata = imagedata
    ws.question = question
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})


def getText(role, imagepath, content):
    imagedata = open(imagepath, "rb").read()

    text = [
        {
            "role": role,
            "content": str(base64.b64encode(imagedata), "utf-8"),
            "content_type": "image",
        },
        {
            "role": role,
            "content": content,
            "content_type": "text",
        },
    ]

    return text


def getlength(text):
    length = 0
    for content in text:
        temp = content["content"]
        leng = len(temp)
        length += leng
    return length


def checklen(text):
    while getlength(text[1:]) > 8000:
        del text[1]
        print("d", end="")
    return text


if __name__ == "__main__":
    raw = """
该图片是否存在图像伪造或篡改的痕迹？（请填是、否、小概率可能、大概率可能）
如果存在伪造篡改痕迹，请问属于哪种篡改或伪造类型？（如copy-move、splice、深模型成图等）
"""
    raw = """该图片从上至下的介绍如下
第一张是原图像
第二张进行了SIFT特征点提取和聚类连线，用于检测图像局部复制粘贴类型的篡改，图中的连线很大程度上说明存在篡改痕迹
第三张是错误水平分析，通过比较有损压缩和原图的差异，提取形成，用于检测压缩水平
第四张是noise variance分析，用于检测图像噪声水平

请分析图片，并按照以下模板回答：
该图片的内容是
该图片几乎不可能/小概率可能/很可能/几乎一定存在篡改痕迹
（如果存在）篡改类型属于copy-move/splice/深度伪造/大模型生成等
"""

    answer = ""
    question = checklen(getText("user", "test/5.jpg", raw))

    main(appid, api_key, api_secret, imageunderstanding_url, question)